import * as vscode from 'vscode';
import { componentCompileLogger } from "./logger/componentCompileLogger";
import { spawn } from "child_process";
import { getRepoPath } from './utils/commonUtils';
import { prebuildDownloadLogger } from './logger/prebuildDownloadLogger';


let isRunning = false;

export function prebuildDownload(args: any[], withDownloadSdk: boolean) {
    if (isRunning) {
        vscode.window.showErrorMessage('Prebuild download is already running, please wait for it to finish');
        return;
    }

    prebuildDownloadLogger.clear();
    
    if (args.length === 0) {
        vscode.window.showErrorMessage('No args provided, please see the log for more information');
        componentCompileLogger.errorWithStack('No args provided');
        return;
    }

    const uri = args[0] as vscode.Uri;
    if (!uri || typeof uri.fsPath !== 'string') {
        vscode.window.showErrorMessage('Invalid URI provided, please see the log for more information');
        componentCompileLogger.errorWithStack('Invalid URI provided');
        return;
    }

    const path = uri.fsPath;
    componentCompileLogger.info(`bundle.json's path is : ${path}`);
    const pathParts = path.split(/[/\\]/);
    const parentFolderName = pathParts.length >= 2 ? pathParts.slice(-2, -1)[0] : '';

    if (!parentFolderName) {
        vscode.window.showErrorMessage('Could not extract parent folder name from path, please see the log for more information');
        componentCompileLogger.errorWithStack('Could not extract parent folder name from path');
        return;
    }
    componentCompileLogger.info(`parentFolderName is : ${parentFolderName}`);

    // 处理路径分隔符，兼容Windows和Unix
    const lastSeparatorIndex = path.lastIndexOf('/') !== -1 ? path.lastIndexOf('/') : path.lastIndexOf('\\');
    const dirPath = path.substring(0, lastSeparatorIndex);
    // Find the root directory containing .repo folder
    const repoRootPath = getRepoPath(dirPath);
    if (!repoRootPath) {
        vscode.window.showErrorMessage('Could not find .repo directory in any parent folder, please see the log for more information');
        componentCompileLogger.errorWithStack('Could not find .repo directory in any parent folder');
        return;
    }

    isRunning = true;
    vscode.window.withProgress({
        location: vscode.ProgressLocation.Notification,
        title: `[${parentFolderName}]: Begin to Prebuild Download...`,
        cancellable: true
    },
    async (progress, token) => {
        try {
            // 执行命令
            const result: { status: string; message: string } = await executeAndLogCommand(withDownloadSdk, dirPath, parentFolderName, token, repoRootPath);

            if (result && result.status === 'success') {
                // 成功时的操作
                vscode.window.showInformationMessage(`[${parentFolderName}]: Prebuild download Success`);
                componentCompileLogger.info(`[${parentFolderName}]: Prebuild download Success`);
                return true;
            } else {
                vscode.window.showErrorMessage(`[${parentFolderName}]: Prebuild download failed, please check the log for more information`);
                componentCompileLogger.error(`[${parentFolderName}]: Prebuild download failed, ${result.message}`);
                return false;
            }
        } finally {
            isRunning = false;
        }
    });
}

/**
 * 执行命令并记录日志
 * @param withDownloadSdk 是否下载sdk
 * @param dirPath bundle.json所在目录的全路径
 * @param parentFolderName bundle.json所在目录的父文件夹名称
 * @param token 取消令牌
 * @param repoRootPath 仓库根目录
 * @returns 执行结果
 */
async function executeAndLogCommand(withDownloadSdk: boolean, dirPath: string, parentFolderName: string, token?: vscode.CancellationToken, repoRootPath?: string): Promise<{ status: string; message: string }> {
    componentCompileLogger.info(`Begin to prebuild download, dirPath is ${dirPath}, parentFolderName is ${parentFolderName}`);
    
    let commandStr = `bash ./build/prebuilts_config.sh`;

    if (withDownloadSdk) {
        commandStr += ` --download-sdk`;
    }

    componentCompileLogger.info(`command is ${commandStr}`);

    // 获取命令执行的工作目录（文件所在目录）
    const workingDir = repoRootPath;
    
    // 将命令字符串分解为命令和参数
    const parts = commandStr.split(' ');
    const command = parts[0];
    const args = parts.slice(1);
    
    const process = spawn(command, args, { 
        cwd: workingDir 
    });

    // 实时处理标准输出
    prebuildDownloadLogger.show();
    process.stdout.on('data', (data) => {
        const output = data.toString().trim();
        if (output) {
            output.split('\n').forEach((line: string) => {
                if (line.trim()) {
                    prebuildDownloadLogger.append(`  ${line}`);
                }
            });
        }
    });
    
    // 实时处理标准错误
    process.stderr.on('data', (data) => {
        const output = data.toString().trim();
        if (output) {
            output.split('\n').forEach((line: string) => {
                if (line.trim()) {
                    prebuildDownloadLogger.append(`  ${line}`);
                }
            });
        }
    });
    
    return new Promise<{ status: string; message: string }>((resolve, reject) => {
        // 保存对取消状态的引用
        let isCancelled = false;
        
        if (token) {
            token.onCancellationRequested(() => {
                isCancelled = true;
                process.kill();
                componentCompileLogger.info(`Prebuild download cancelled by user`);
                reject({ status: 'failed', message: 'Prebuild download cancelled by user' });
            });
        }
        
        process.on('close', (code) => {
            // 如果已经因为取消而解析了，就不要重复解析
            if (isCancelled) {
                return;
            }
            
            if (code === 0) {
                resolve({ status: 'success', message: 'Prebuild download success' });
            } else {
                const errorMsg = `命令 ${commandStr} 执行失败，退出码: ${code}`;
                reject({ status: 'failed', message: errorMsg });
            }
        });
        
        process.on('error', (err) => {
            // 如果已经因为取消而解析了，就不要重复解析
            if (isCancelled) {
                return;
            }
            const errorMsg = `command execution error: ${err.message}`;
            reject({ status: 'failed', message: errorMsg });
        });
    }).then((result: { status: string; message: string }) => {
        return result;
    }).catch((result: { status: string; message: string }) => {
        return result;
    });
}